use crate::utils::{cache_util, date_util::get_now_time_m, mysql_utils::get_connect};
use serde::{Deserialize, Serialize};
use sqlx::{sqlite::SqliteRow, Row};

#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Ageing {
    pub id: String,
    pub date: String,
    pub work_time: f64,
    pub work_num: f64,

    pub create_time: i64,
    pub creator_lid: String,
    pub creator_name: String,
    pub updater_lid: String,
    pub updater_name: String,
    pub up_ver: i16,
    pub sort: i16,
    pub tenant_id: i64,
    pub deleted: i64,
    pub update_time: i64,
}

impl Default for Ageing {
    fn default() -> Self {
        Ageing {
            id: String::from(""),
            date: String::from(""),
            work_time: 0.0,
            work_num: 0.0,
            create_time: 0,
            creator_lid: String::from(""),
            creator_name: String::from(""),
            updater_lid: String::from(""),
            updater_name: String::from(""),
            up_ver: 0,
            sort: 0,
            tenant_id: 0,
            deleted: 0,
            update_time: 0,
        }
    }
}

pub async fn get_list_by_date(date: String) -> Option<Vec<Ageing>> {
    let list: Option<Vec<Ageing>> = cache_util::get_cache_with_regex_match_(&date).await;
    match list {
        Some(list) => {
            if !list.is_empty() {
                return Some(list);
            }
        }
        None => {
            log::info!("缓存中获取为空！")
        }
    }

    let mut conn = get_connect()
        .acquire()
        .await
        .expect("Error get_connect from db pool");
    let rust = sqlx::query("select id, date, work_time, work_num, create_time, update_time from ageing where date like '%?%'")
    .bind(date)
    .map(|row: SqliteRow| {
        Ageing{ id: row.get(0), date: row.get(1), work_time: row.get(2), work_num: row.get(3), create_time: row.get(4), 
            creator_lid: String::from(""), creator_name: String::from(""), updater_lid: String::from(""), updater_name: String::from(""), up_ver: 0, sort: 0, tenant_id: 0, deleted: 0, 
            update_time: row.get(5)}
    })
    .fetch_all(&mut *conn)
    .await;

    match rust {
        Ok(rest) => {
            for i in rest.iter() {
                cache_util::set_cache_(i.date.clone(), i.clone(), None).await;
            }
            return Some(rest);
        }
        Err(e) => {
            log::error!("失败{}", e);
            return None;
        }
    }
}

pub async fn get_list_by_dates(dates: Vec<String>) -> Option<Vec<Ageing>> {
    if dates.is_empty() {
        return None;
    }
    let mut list = vec![];
    for date in dates.iter() {
        let cache: Option<Ageing> = cache_util::get_cache_(date).await;
        match cache {
            Some(data) => {
                list.push(data);
            }
            None => {
                log::info!("缓存获取为空~！");
            }
        }
    }
    if list.len() == dates.len() {
        return Some(list);
    }

    // 生成与 dates 长度对应的占位符（例如："?,?,?"）
    let placeholders = vec!["?"; dates.len()].join(", ");
    let sql = format!(
        "SELECT id, date, work_time, work_num, create_time, update_time 
         FROM ageing 
         WHERE date IN ({})",
        placeholders
    );
    let mut conn = get_connect()
        .acquire()
        .await
        .expect("Error get_connect from db pool");
    let mut query = sqlx::query(&sql);
    for date in &dates {
        query = query.bind(date);
    }

    let rust = query
        .map(|row: SqliteRow| Ageing {
            id: row.get(0),
            date: row.get(1),
            work_time: row.get(2),
            work_num: row.get(3),
            create_time: row.get(4),
            creator_lid: String::from(""),
            creator_name: String::from(""),
            updater_lid: String::from(""),
            updater_name: String::from(""),
            up_ver: 0,
            sort: 0,
            tenant_id: 0,
            deleted: 0,
            update_time: row.get(5),
        })
        .fetch_all(&mut *conn)
        .await;

    match rust {
        Ok(rest) => {
            for i in rest.iter() {
                cache_util::set_cache_(i.date.clone(), i.clone(), None).await;
            }
            return Some(rest);
        }
        Err(e) => {
            log::error!("失败{}", e);
            return None;
        }
    }
}

pub async fn save(info: Ageing) -> bool {
    let mut conn = get_connect()
        .acquire()
        .await
        .expect("Error get_connect from db pool");
    let now = get_now_time_m();
    let temp = info.clone();
    let result = sqlx::query("insert into ageing (id, date, work_time, work_num, create_time, update_time, deleted) values (?,?,?,?,?,?,?)")
    .bind(info.id).bind(info.date).bind(info.work_time).bind(info.work_num).bind(now).bind(now).bind(0)
    .execute(&mut *conn)
    .await;

    match result {
        Ok(_) => {
            cache_util::set_cache_(temp.date.clone(), temp.clone(), None).await;
            log::info!("创建数据成功");
            return true;
        }
        Err(e) => {
            log::error!("{}", e);
            log::error!("创建数据失败");
            return false;
        }
    }
}

pub async fn update_by_date(info: Ageing) -> bool {
    let mut conn = get_connect()
        .acquire()
        .await
        .expect("Error get_connect from db pool");
    let temp = info.clone();
    let result = sqlx::query("UPDATE ageing SET work_time = ?, work_num=? where date = ?")
        .bind(info.work_time)
        .bind(info.work_num)
        .bind(info.date)
        .execute(&mut *conn)
        .await;

    match result {
        Ok(_) => {
            cache_util::set_cache_(temp.date.clone(), temp.clone(), None).await;
            log::info!("创建数据成功");
            return true;
        }
        Err(e) => {
            log::error!("{}", e);
            log::error!("创建数据失败");
            return false;
        }
    }
}

pub async fn get_info_by_date(date: String) -> Option<Ageing> {
    let mut conn = get_connect()
        .acquire()
        .await
        .expect("Error get_connect from db pool");
    let rust = sqlx::query(
        "select id, date, work_time, work_num, create_time, update_time from ageing where date = ?",
    )
    .bind(date)
    .map(|row: SqliteRow| Ageing {
        id: row.get(0),
        date: row.get(1),
        work_time: row.get(2),
        work_num: row.get(3),
        create_time: row.get(4),
        creator_lid: String::from(""),
        creator_name: String::from(""),
        updater_lid: String::from(""),
        updater_name: String::from(""),
        up_ver: 0,
        sort: 0,
        tenant_id: 0,
        deleted: 0,
        update_time: row.get(5),
    })
    .fetch_all(&mut *conn)
    .await;

    match rust {
        Ok(rest) => {
            if let Some(res) = rest.get(0) {
                cache_util::set_cache_(res.date.clone(), res.clone(), None).await;
                return Some(res.clone());
            }
            return None;
        }
        Err(e) => {
            log::error!("失败{}", e);
            return None;
        }
    }
}
